<!-- 地图模块初始化加载 -->
<template>
<div class="map-container">
    <!-- 地图 -->
    <div id="main_map" class="main-map">
        <div id="scaleBarDiv"></div>
        <!-- 右侧工具条 -->
        <div class="righttools" style="width: 40px; height: 80px; background: #fff; z-index: 99; position: absolute; right: 20px; top: 120px; border-radius: 5px; padding: 2px 0vw; border: 1px solid #f3f3f3;">
            <div v-for="(item,index) in rightTools" :key="index" @click="_rightToolsBtn(item)" style="height:40px;" :style="index!=rightTools.length-1? {borderBottom: '1px solid #f3f3f3'}: {}">
                <div style="text-align: center;height: 20px;">
                    <img v-show="!item.select" style="height: 12px; margin-top: 5px;" :src="item.img" />
                    <img v-show="item.select" style="height: 12px; margin-top: 5px;" :src="item.img2" />
                </div>
                <div style="text-align: center;">
                    <span v-show="!item.select" style="color:#2c3e50;">{{item.title}}</span>
                    <span v-show="item.select" style="color:#1989fa;">{{item.title}}</span>
                </div>
            </div>
        </div>
        <!-- 左下放大缩小 -->
        <div class="zoomTools" style="bottom: 100px; width: 40px; height: 70px; background: #fff; z-index: 99; position: fixed; left: 20px; border-radius: 5px; padding: 2px; border: 1px solid #f3f3f3;">
            <div @click="_zoom('in')" style="text-align: center;height: 32px;padding: 5px 0px; margin: 5px 5px;border-bottom:1px solid #f3f3f3">
                <img style="height: 20px;" src="https://nfzjszlb.jst.zj.gov.cn/security/zoomin.png" />
            </div>
            <div @click="_zoom('out')" style="text-align: center;height: 32px; margin: 5px 5px;">
                <img style="height: 20px;" src="https://nfzjszlb.jst.zj.gov.cn/security/zoomout.png" />
            </div>
        </div>
        <!-- 定位 -->
        <div class="location" style="width: 40px; height: 40px; bottom: 45px; background: #fff; z-index: 99; position: fixed; left: 20px; border-radius: 5px; padding: 2px 0px; border: 1px solid #f3f3f3;">
            <div @click="_getIPxy" style="text-align: center;height: 32px;padding: 5px 0px; margin: 5px 5px;">
                <img style="height: 20px;" src="https://nfzjszlb.jst.zj.gov.cn/security/location.png" />
            </div>
        </div>
        <!-- i查询 -->
        <i-query ref="iqueryref" v-if="showiQuery"></i-query>
    </div>

</div>
</template>

<script>
import Pubsub from 'pubsub-js'
import CryptoJS from "crypto-js";
import * as esriLoader from "esri-loader";
import MapManager from "../../core/mapManager";
import iQuery from "./public/iQuery.vue"

export default {
    name: "MapContainer",
    props: {},
    data() {
        return {
            ak: "BDv3WGThhC19xh6bVCjALzUscGSWxzaS", //这里是密钥，秘钥去百度地图申请
            initBaseMapType: "影像图",
            mapView: null,
            active3D: false,
            rightTools: [{
                    title: "图层",
                    btn: "baseMapToggle",
                    select: false,
                    img: "https://nfzjszlb.jst.zj.gov.cn/security/shigong.png",
                    img2: "https://nfzjszlb.jst.zj.gov.cn/security/shigong-x.png"
                },
                {
                    title: "查看",
                    btn: "iQuery",
                    select: false,
                    img: "https://nfzjszlb.jst.zj.gov.cn/security/chakan.png",
                    img2: "https://nfzjszlb.jst.zj.gov.cn/security/chakan-x.png"
                }
            ],
            showiQuery: false,
        };
    },

    components: {
        iQuery,
    },

    computed: {},
    //注意：修改组件请添加对应的修改版本、日期、功能、注释！！！！
    //方法：方法命名请以下划线_开头！！！！
    //其它项复制粘贴过来的代码，请将无用的参数删除，一个js类用到一个方法不要粘整个js过来！！！！
    methods: {
        //获取url地址中的某一个参数值
        _getUrlParam(paraName) {
            var url = document.location.toString();
            var arrObj = url.split("?");

            if (arrObj.length > 1) {
                var arrPara = arrObj[1].split("&");
                var arr;
                for (var i = 0; i < arrPara.length; i++) {
                    arr = arrPara[i].split("=");
                    if (arr != null && arr[0] == paraName) {
                        return arr[1];
                    }
                }
                return "";
            } else {
                return "";
            }
        },
        //设置初始化范围
        _goInitExtent() {
            if (window.g.MapConfiguration.FullViewInfo) {
                const p = new this.Point({
                    x: window.g.MapConfiguration.FullViewInfo.center.x,
                    y: window.g.MapConfiguration.FullViewInfo.center.y,
                    spatialReference: this.mapView.spatialReference,
                });
                this.mapView.goTo({
                    target: p,
                    zoom: window.g.MapConfiguration.FullViewInfo.zoom
                }, {
                    easing: "ease-out",
                    duration: 1000
                });
            } else {
                if (this.initExtent && this.mapView) {
                    this.mapView.goTo(this.initExtent, {
                        easing: "ease-out",
                        duration: 1000,
                    });
                }
            }
        },
        //地图初始化加载
        _initMap() {
            const self = this
            //1、视图存在则先进行移除
            if (this.mapView) {
                this.mapView.ui.empty();
                if (this.compass) this.compass.destroy();
                if (this.scaleBar) this.scaleBar.destroy();
                MapManager.removeMapViewByID("mainMap");
                this.mapView = null;
            }
            //2、加载地图相关资源
            esriLoader
                .loadModules([
                    "esri/Map",
                    "esri/views/MapView",
                    "esri/Basemap",
                    "esri/geometry/Point",
                    'esri/geometry/Polyline',
                    "esri/geometry/Polygon",
                    "esri/geometry/Extent",
                    "esri/layers/TileLayer",
                    "esri/layers/support/TileInfo",
                    "esri/layers/MapImageLayer",
                    "esri/layers/FeatureLayer",
                    "esri/layers/GraphicsLayer",
                    "esri/layers/WebTileLayer",
                    "esri/layers/WMTSLayer",
                    "esri/geometry/SpatialReference",
                    "esri/core/watchUtils",
                    "esri/widgets/ScaleBar",
                    "esri/widgets/Compass",
                    "esri/Graphic",
                    'esri/config',
                    "esri/widgets/Zoom",
                    "esri/geometry/geometryEngine",
                ])
                .then(([
                    Map,
                    MapView,
                    Basemap,
                    Point,
                    Polyline,
                    Polygon,
                    Extent,
                    TileLayer,
                    TileInfo,
                    MapImageLayer,
                    FeatureLayer,
                    GraphicsLayer,
                    WebTileLayer,
                    WMTSLayer,
                    SpatialReference,
                    watchUtils,
                    ScaleBar,
                    Compass,
                    Graphic,
                    esriConfig,
                    Zoom,
                    geometryEngine,
                ]) => {
                    self.Map = Map
                    self.MapView = MapView
                    self.Basemap = Basemap
                    self.Point = Point
                    self.Polyline = Polyline
                    self.Polygon = Polygon
                    self.Extent = Extent
                    self.TileLayer = TileLayer
                    self.TileInfo = TileInfo
                    self.MapImageLayer = MapImageLayer
                    self.FeatureLayer = FeatureLayer
                    self.GraphicsLayer = GraphicsLayer
                    self.WebTileLayer = WebTileLayer
                    self.WMTSLayer = WMTSLayer
                    self.SpatialReference = SpatialReference
                    self.watchUtils = watchUtils
                    self.ScaleBar = ScaleBar
                    self.Compass = Compass
                    self.Graphic = Graphic
                    self.esriConfig = esriConfig
                    self.Zoom = Zoom;
                    self.geometryEngine = geometryEngine;
                    //设置静态资源
                    if (window.g.MapConfiguration.ArcGIS_Fonts_Path) {
                        esriConfig.fontsUrl = window.g.MapConfiguration.ArcGIS_Fonts_Path
                    }
                    //设置初始化范围                    
                    let initExtent = new Extent(window.g.MapConfiguration.InitExtent);
                    self.initExtent = initExtent.expand(1.1);
                    //设置底图资源
                    const configBaseMaps = window.g.MapConfiguration.BaseMaps;
                    configBaseMaps.sort((a, b) => {
                        return b.order - a.order;
                    });
                    self.initBaseMapType = configBaseMaps[2] ? configBaseMaps[2].class : "电子地图";
                    let tileInfo = null;
                    if (window.g.MapConfiguration.TileInfoOptions) {
                        tileInfo = new TileInfo(window.g.MapConfiguration.TileInfoOptions)
                    }
                    const baseLayers = [];
                    configBaseMaps.forEach((m, index) => {
                        let initLayer = null;
                        switch (m.type) {
                            case "tile":
                                if (tileInfo && m.isCustomTile) {
                                    initLayer = new self.TileLayer({
                                        url: m.url,
                                        title: m.title,
                                        tileInfo: tileInfo,
                                    });
                                } else {
                                    initLayer = new TileLayer({
                                        url: m.url,
                                        title: m.title,
                                    });
                                }
                                break;
                            case "feature":
                                initLayer = new self.FeatureLayer({
                                    url: m.url,
                                    title: m.title,
                                });
                                break;
                            case "wmts":
                                initLayer = new self.WMTSLayer({
                                    url: m.url,
                                    title: m.title,
                                    customParameters: m.customParameters,
                                    activeLayer: m.activeLayer,
                                });
                                break;
                            case "web-tile":
                                let urlTemplate = m.urlTemplate;
                                initLayer = new self.WebTileLayer({
                                    urlTemplate: urlTemplate,
                                    title: m.title,
                                    tileInfo: tileInfo,
                                    fullExtent: new self.Extent({
                                        xmax: 180,
                                        xmin: -180,
                                        ymax: 90,
                                        ymin: -90,
                                        spatialReference: {
                                            wkid: 4490,
                                        },
                                    }),
                                    spatialReference: tileInfo.spatialReference,
                                    subDomains: m.subDomains,
                                });
                                break;
                            default:
                                initLayer = new self.MapImageLayer({
                                    url: m.url,
                                    title: m.title,
                                });
                                break;
                        }
                        if (initLayer) {
                            initLayer.isBaseMap = true;
                            initLayer.id = "BaseMap_" + index;
                            initLayer.class = m.class;
                            initLayer.visible = m.class === self.initBaseMapType
                            baseLayers.push(initLayer)
                        }
                    });

                    const baseMaps = new Basemap({
                        baseLayers: baseLayers,
                        title: '底图',
                        id: 'BaseMaps',
                    })
                    const mainMap = new Map({
                        basemap: baseMaps
                    })
                    self.mapView = new MapView({
                        map: mainMap,
                        container: 'main_map',
                        extent: initExtent.expand(0.8),
                        spatialReference: initExtent.spatialReference,
                        constraints: {
                            rotationEnabled: false
                        }
                    })
                    if (window.g.MapConfiguration.InitExtent.zoom) {
                        self.mapView.zoom = window.g.MapConfiguration.InitExtent.zoom;
                    }
                    if (window.g.MapConfiguration.InitExtent.scale) {
                        self.mapView.scale = window.g.MapConfiguration.InitExtent.scale;
                    }
                    //移除默认小组件
                    self.mapView.ui.empty("top-left");
                    self.mapView.ui.remove("attribution");
                    //设置添加比例尺
                    self.scaleBar = new self.ScaleBar({
                        id: "scaleBar",
                        container: "scaleBarDiv",
                        view: self.mapView,
                        unit: "metric",
                    });
                    self.mapView.ui.add(self.scaleBar, {
                        position: "bottom-left",
                    });
                    //设置通用弹框样式
                    self.mapView.popup = {
                        highlightEnabled: true,
                        updateLocationEnabled: true,
                        dockEnabled: false,
                        dockOptions: {
                            buttonEnabled: false,
                            breakpoint: true,
                            position: 'bottom-center'
                        },
                    }
                    //地图视图资源加载完成后操作                    
                    self.mapView.when(() => {
                        //保存视图其它组件方可使用
                        MapManager.saveMapView(self.mapView, "mainMap");
                        self._goInitExtent();
                        //设置缩放
                        self.mapZoom = new self.Zoom({
                            view: self.mapView
                        });
                        //添加市级、区县要素
                        self.cityDivisions = MapManager.getAdministrativeDivisions()
                        self.blockDivisions = MapManager.getAdministrativeDivisions(1)
                        // //添加遮罩
                        // self._setShade()
                        self._setInterceptors()
                    })
                    // //注意！！！每次地图新添加一个图层后，需要将掩膜图层置顶------移动端不再添加掩膜
                    // self.layersWatcher = self.watchUtils.watch(self.mapView.map.allLayers, 'length', event => {
                    //     //遮罩图层置顶
                    //     let zhezhaoLayer = MapManager.getLayerFromID(self.mapView, "xzqhGraphicsLayer")
                    //     if (zhezhaoLayer) { //省级没有遮罩
                    //         this.mapView.map.reorder(zhezhaoLayer, self.mapView.map.allLayers.items.length);
                    //     }
                    // });

                }).catch((e) => {
                    console.error("初始化地图出错——");
                    console.error(e);
                });

        },
        // 添加拦截器
        _setInterceptors() {
            const self = this
            // 截取域名
            function domainURI(durl) {
                let urlReg = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/;
                let domain = urlReg.exec(durl);
                return domain ? domain[0] : null;
            }
            self.esriConfig.request.interceptors = []
            self.esriConfig.request.interceptors.push({
                before: function (params) {
                    const domain = domainURI(params.url)
                    const nf_domain = domainURI(window.g.BaseUrlMap)
                    //   农房接口使用农房授权appkey
                    if (domain && params.requestOptions && nf_domain === domain) {
                        const appkey = "6738c85b-69e8-11ec-a673-6805cab640a0" //window.g.MapConfiguration.APPKEY
                        const appsecreat = "801ba32b6f9811ed9a386805cab597a8" //window.g.MapConfiguration.APPSECRET
                        let time = Date.now().toString();
                        let sign = CryptoJS.enc.Hex.stringify(
                            CryptoJS.MD5(appkey + appsecreat + time)
                        );
                        params.requestOptions.headers = {
                            sign: sign,
                            timestamp: time,
                            appkey: appkey
                        }
                    }
                },
            });
        },
        //根据用户设置对应的省、市、县掩膜遮罩
        _setShade作废() {
            const self = this
            //1、获取当前用户的范围
            let cityCode = self._getUrlParam("cityCode")
            let level = "省级"
            if (cityCode.substring(0, 12) === "330000000000") {
                level = "省级"
            } else if (cityCode.substring(4, 12) === "00000000") {
                level = "市级";
            } else if (cityCode.substring(6, 12) === "000000") {
                level = "区县";
            } else if (cityCode.substring(9, 12) === "000") {
                level = "乡镇";
            } else {
                level = "乡镇";
                cityCode = cityCode.substring(0, 8) + "0000";
            }

            let markGeoSet = null;
            if (level == "省级") {
                //添加边界线
                self.divisionBaseLayerLine = new self.GraphicsLayer({ //用于画边界线,否则看不到边界
                    id: "xzqhGraphicsLayerLine",
                });
                self.divisionBaseLayerLine.class = "isBase";
                self.mapView.map.addMany([self.divisionBaseLayerLine]);
                self.cityDivisions.forEach(ele => {
                    let division1 = Object.assign({}, ele);
                    const g = new self.Graphic({
                        geometry: division1.geometry,
                        symbol: {
                            type: "simple-fill",
                            color: "rgba(255, 255, 255, 0)",
                            outline: {
                                color: 'rgba(163, 224, 255, 1)',
                                width: 2,
                            },
                        },
                    });
                    self.divisionBaseLayerLine.add(g);
                })
                self.mapView.constraints.minScale = window.g.MapConfiguration.XZQH_ScaleLimit[level];
                return;
            } else if (level == "市级") {
                for (let index = 0; markGeoSet == null && index < self.cityDivisions.length; index++) {
                    const element1 = self.cityDivisions[index];
                    let division1 = Object.assign({}, element1);
                    if (division1.attributes.code.substring(0, 4) == cityCode.substring(0, 4)) {
                        markGeoSet = division1.geometry
                        break;
                    }
                }
            } else if (level == "区县") {
                for (let index2 = 0; markGeoSet == null && index2 < self.blockDivisions.length; index2++) {
                    const element2 = self.blockDivisions[index2];
                    let division2 = Object.assign({}, element2);
                    if (division2.attributes.code.substring(0, 6) == cityCode.substring(0, 6)) {
                        markGeoSet = division2.geometry
                        break;
                    }
                }
            }

            //2、新建遮罩图层
            self.divisionBaseLayer = new self.GraphicsLayer({
                id: "xzqhGraphicsLayer",
                opacity: 1,
                blendMode: "destination-in",
                effect: "brightness(1.5) drop-shadow(0, 0px, 12px)",
            });
            self.divisionBaseLayer.class = "isBase";
            self.divisionBaseLayerLine = new self.GraphicsLayer({ //用于画边界线,否则看不到边界
                id: "xzqhGraphicsLayerLine",
            });
            self.divisionBaseLayerLine.class = "isBase";
            self.mapView.map.addMany([self.divisionBaseLayer, self.divisionBaseLayerLine]);

            //3、添加图形范围
            const g = new self.Graphic({
                geometry: markGeoSet,
                symbol: {
                    type: "simple-fill",
                    color: "rgba(255, 255, 255, 1)",
                    outline: {
                        color: 'rgba(163, 224, 255, 1)',
                        width: 2,
                    },
                },
            });
            let g2 = g.clone();
            g2.symbol.color = "rgba(255, 255, 255, 0)"
            self.divisionBaseLayer.add(g);
            self.divisionBaseLayerLine.add(g2);
            self.mapView.constraints.geometry = markGeoSet.extent.expand(1.2);
            self.mapView.goTo({
                target: markGeoSet.extent.expand(1.2)
            }, {
                easing: "ease-out",
                duration: 1000
            });

            //4、限制显示对应的范围
            self.mapView.constraints.minScale = window.g.MapConfiguration.XZQH_ScaleLimit[level];
        },
        //右侧工具点击事件
        _rightToolsBtn(item) {
            const self = this
            item.select = !item.select
            switch (item.btn) {
                case "baseMapToggle":
                    self._baseMapToggle()
                    break;
                case "iQuery":
                    self.showiQuery = !self.showiQuery
                    break;
            }
        },
        //电子地图、影像地图切换
        _baseMapToggle() {
            const self = this
            if (self.initBaseMapType == "电子地图") {
                self.initBaseMapType = "影像地图"
            } else {
                self.initBaseMapType = "电子地图"
            }
            //重新设置四个底图的显示
            self.mapView.map.basemap.baseLayers.items.forEach(layer => {
                if (layer.class == self.initBaseMapType) {
                    layer.visible = true
                } else {
                    layer.visible = false
                }
            })
        },
        //放大和缩小
        _zoom(type) {
            if (type == "in") {
                this.mapZoom.zoomIn()
            } else if (type == "out") {
                this.mapZoom.zoomOut()
            }
        },
        //获取当前ip经纬度地址(高德图)，并进行定位      
        _getIPxy高德方法已作废() {
            const self = this
            AMap.plugin('AMap.Geolocation', function () {
                var geolocation = new AMap.Geolocation({
                    // 是否使用高精度定位，默认：true
                    enableHighAccuracy: true,
                    // 设置定位超时时间，默认：无穷大
                    timeout: 10000,
                    // 定位按钮的停靠位置的偏移量，默认：Pixel(10, 20)
                    buttonOffset: new AMap.Pixel(10, 20),
                    //  定位成功后调整地图视野范围使定位位置及精度范围视野内可见，默认：false
                    zoomToAccuracy: true,
                    //  定位按钮的排放位置,  RB表示右下
                    buttonPosition: 'RB'
                })
                geolocation.getCurrentPosition((status, result) => {
                    console.log("_getIPxy:", status, result)
                    if (status == "complete") {
                        //正式代码
                        // let locationX = result.position.lng
                        // let locationY = result.position.lat
                        // //测试代码
                        let locationX = "120.15956112770424"
                        let locationY = "30.3055819173615"
                        let point = new self.Point({
                            x: locationX,
                            y: locationY,
                            spatialReference: self.mapView.spatialReference
                        })
                        //根据经纬度获取当前用户所在区县,并定位到用户区县
                        self.blockDivisions.forEach(quxian => {
                            const isContained = self.geometryEngine.contains(quxian.geometry, point);
                            if (isContained) {
                                //定位到当前区划
                                self.mapView.goTo({
                                    target: quxian.geometry.extent.center,
                                    // zoom: 16
                                }, {
                                    easing: "ease-out",
                                    duration: 1000
                                });
                            }
                        })
                    } else {
                        console.info("获取当前定位失败");
                    }
                })
            })
        },
        //获取当前ip经纬度地址(百度地图)，并进行定位
        _getIPxy() {
            const self = this
            self.$nextTick(() => {
                var geolocation = new BMapGL.Geolocation();
                geolocation.getCurrentPosition(function (r) {
                    if (this.getStatus() == BMAP_STATUS_SUCCESS) {
                        //正式代码
                        let locationX = r.longitude
                        let locationY = r.latitude
                        console.log("ip位置", r)
                        // //测试代码
                        // let locationX = "120.15956112770424"
                        // let locationY = "30.3055819173615"
                        let point = new self.Point({
                            x: locationX,
                            y: locationY,
                            spatialReference: self.mapView.spatialReference
                        })
                        self.mapView.goTo({
                            target: point
                        },{
                            easing: "ease-out",
                            duration: 1000
                        })
                        // //根据经纬度获取当前用户所在区县,并定位到用户区县
                        // self.blockDivisions.forEach(quxian => {
                        //     const isContained = self.geometryEngine.contains(quxian.geometry, point);
                        //     if (isContained) {
                        //         //定位到当前区划
                        //         self.mapView.goTo({
                        //             target: quxian.geometry.extent.center,
                        //         }, {
                        //             easing: "ease-out",
                        //             duration: 1000
                        //         });
                        //         // Pubsub.publish("gotoFeature", quxian)
                        //     }
                        // })
                    } else {
                        console.info('获取当前定位失败' + this.getStatus());
                    }
                });
            })
        },

    },

    mounted() {
        this._initMap();
    },

    beforeDestroy() {
        this.mapView.graphics.removeAll()
        if (this.layersWatcher) {
            this.layersWatcher.remove();
            this.layersWatcher = undefined;
        }
    },

}
</script>

<style lang="scss" scoped>
.map-container {
    position: relative;
    z-index: 10;
    height: 100vh;
    width: 100vw;
    background-size: 100% 100%;
    overflow: hidden;
    float: left;
}

.main-map {
    width: 100%;
    height: 100%;
    background-color: white;
}

/*.map-container .righttools {
    width: 40px;
    height: 80px;
    background: #fff;
    z-index: 99;
    position: absolute;
    right: 20px;
    top: 120px;
    border-radius: 5px;
    padding: 2px 0vw;
    border: 1px solid #f3f3f3;
}

.map-container .zoomTools {
    bottom: 100px;
    width: 40px;
    height: 70px;
    background: #fff;
    z-index: 99;
    position: fixed;
    left: 20px;
    border-radius: 5px;
    padding: 2px;
    border: 1px solid #f3f3f3;
}

.map-container .location {
    width: 40px;
    height: 40px;
    bottom: 45px;
    background: #fff;
    z-index: 99;
    position: fixed;
    left: 20px;
    border-radius: 5px;
    padding: 2px 0px;
    border: 1px solid #f3f3f3;
}*/
</style>
